<?php
// +----------------------------------------------------------------------
// | 海豚PHP框架 [ DolphinPHP ]
// +----------------------------------------------------------------------
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
// +----------------------------------------------------------------------
// | 官方网站: http://dolphinphp.com
// +----------------------------------------------------------------------

namespace app\mill\model;

use think\Model;
use app\mill\model\Archives as ArchivesModel;
use app\admin\model\Config as ConfigModel;
use think\Db;

/**
 * 产品流水模型
 */
class Give extends Model
{
    // 设置当前模型对应的完整数据表名称
    protected $name = 'mill_order_archives_give';

    // 自动写入时间戳
    protected $autoWriteTimestamp = true;

    // 条形码每页显示数
    public static $_listRows = 500;

    //生产状态状态
    public static $give_status = [
        -1 =>      '开料报废',
        -2 =>      '钣金报废',
        -3 =>      '喷涂报废',
        -4 =>      '复合报废',
        -5 =>      '发货报废',
        0 =>      '待生产',
        1 =>      '开料',
        2 =>      '钣金',
        3 =>      '喷涂',
        4 =>      '复合',
        5 =>      '发货',
    ];

    //生产状态状态
    public static $give_status_search = [
        0 =>      '待生产',
        1 =>      '开料',
        //2 =>      '钣金',
        //3 =>      '喷涂',
        //4 =>      '复合',
        5 =>      '发货',
    ];

    //生产质检状态
    public static $quality_status = [
        -1 =>     '不合格',
        -2 =>     '报废',
        -3 =>     '已取消',
        0 =>      '待质检',
        1 =>      '合格',
        2 =>      '已返修',
    ];

    //打印状态
    public static $quality_repair = [
        0 =>      '待打印',
        1 =>      '待补件',
        2 =>      '已打印',
    ];

    //各部门权限
    //process:是否需要复合
    public static $role = [
        4   =>    ['quality'=>[true]],//质检部
        5   =>    ['status'=>[1]],//开料部
        6   =>    ['status'=>[2,1]],//钣金部
        7   =>    ['status'=>[3,2,1],'color'=>[true],'sub'=>[true]],//喷涂部
        //7   =>    ['status'=>[3,2,1],'color'=>[true]],//喷涂部
        8   =>    ['status'=>[5,4,3,2,1]],//发货部
        9   =>    ['status'=>[4,3,2,1]],//补扫部
        10  =>    ['status'=>[4,3,2,1]],//复合部
    ];

    //责任部门
    public static $quality_group = [
        1    =>    5,//开料部
        2    =>    6,//钣金部
        3    =>    7,//喷涂部
        4    =>    10,//复合部
        5    =>    8,//发货部
    ];

    //各车间不需要的流水线配置
    public static $role_mill = [
        0   =>    [4],//复合
        1   =>    false,
    ];

    //配置可自动补扫的部门及需要补充到的状态
    public static $sup = [
        6    =>    1,//钣金部
        7    =>    2,//喷涂部
        8    =>    4,//发货部
        10   =>    3,//复合部
    ];

    //配置补扫部门ID
    public static $sup_group = 9;

    // 配置产品编号
    public static function giveSn($date=null,$batch=1,$sort=1){
        if(!$date)$date = time();
        else $date = count($date)==10?$date:strtotime($date);
        $date = date('ymd',$date);
        return $date.sprintf ("%03d", $batch)."-".sprintf ("%03d", $sort);
    }

    // 配置发货单号
    public static function addressSn($time=0,$sort=null){
        $config = new ConfigModel();

        if(!$time)$time = time();
        //$date = date('ym',$time);
        $date = date('Ymd',$time);
        //if(!$sort)$sort = $config->getConfig('mill_address_sn');

        return $date."-".sprintf ("%04d", $sort);
    }

    //验证部门API操作权限
    public static function role($user=[],$status=null,$quality_status=null){

        if(is_numeric($quality_status) && $quality_status == 0)$quality_status = true;
        $s = is_numeric($status)?[$status,'status']:[$quality_status,'quality'];
        if(!empty($user) && !empty(self::$role[$user['group']][$s[1]]) && in_array($s[0],self::$role[$user['group']][$s[1]]))return false;

        if(is_numeric($status) && empty(self::$give_status[$status]))return '已出库';

        $note = is_numeric($status)?self::$give_status[$status]:'质检';

        return "无[{$note}]权限";
    }

    //验证部门API是否需要确认流程
    public static function role_sub($user=[],$update=[],$sub=0,$give_status=0){

        $s = [true,'sub'];
        if(!empty($user) && !empty(self::$role[$user['group']][$s[1]]) && in_array($s[0],self::$role[$user['group']][$s[1]])){
            $status = $update['status'];
            $sub ++;
            if($sub == 1){
                if($give_status < 0){
                    $update['status'] --;
                }
                else unset($update['status']);
            }
            elseif ($sub == 2){
                unset($update['status_flow']);
            }
            $update["status{$status}_sub"] = $sub;

        }

        return $update;
    }

    //验证车间不需要的流水线
    public static function roleMill($user=[],$status=null,$is_process=null){

        if(self::roleMillBool($user,$status,$is_process))$status ++;

        return $status;
    }
    //验证车间不需要的流水线
    public static function roleMillBool($user=[],$status=null,$is_process=null){

        if($is_process == 0 && $user['group'] == 8)$user['mill_id'] = 0;
        if(!empty($user) && !empty(self::$role_mill[$user['mill_id']]) && in_array($status,self::$role_mill[$user['mill_id']]))return true;

        return false;
    }

    //补一件产品
    public static function repair($id=null,$is_old_id=true){

        $where = ['id'=>$id];
        $give = Db::name('mill_order_archives_give')->where($where)->find();

        $quality_old_id = $give['id'];
        $quality_repair = 1;
        //是否录入补件产品信息
        if(empty($is_old_id)){
            $quality_old_id = '';
            $quality_repair = '';
        }

        //获取最后一件产品的计件数
        $counter = Db::name('mill_order_archives_give')
            ->where(['archives_id'=>$give['archives_id']])
            ->order('counter desc')
            ->value('counter');
        $counter++;//计件数+1
        //获取最后一件产品的序列
        $sort = Db::name('mill_order_archives_give')
            ->where(['give_date'=>$give['give_date'],'batch'=>$give['batch']])
            ->order('sort desc')
            ->value('sort');
        $sort++;//计件数+1
        $add = [
            'quality_old_id'        =>  $quality_old_id,
            'quality_repair'        =>  $quality_repair,
            'order_id'              =>  $give['order_id'],
            'order_pid'             =>  $give['order_pid'],
            'archives_id'           =>  $give['archives_id'],
            'archives_sn'           =>  $give['archives_sn'],
            'counter'               =>  $counter,
            'give_date'             =>  $give['give_date'],
            'batch'                 =>  $give['batch'],
            'sort'                  =>  $sort,
            'give_sn'               =>  self::giveSn($give['give_date'],$give['batch'],$sort),
        ];

        Db::name('mill_order_archives_give')->insert($add);
    }

    /**
     * 补足产品的补货状态
     * @param array $user 用户ID
     * @param string $status_flow 产品各状态组装
     * @param int $status 当前状态
     * @param int $do_status 补充到截止状态
     * @param array $give 产品信息
     * @return mixed
     */
    public static function giveToStatus4($user = [],$status_flow = '',$status = 0,$do_status = 4,$give=[]){
        //获取补扫部门的一个账号
        $uid = Db::name('admin_user')->where(['group'=>self::$sup_group,'mill_id'=>$user['mill_id']])->value('id');
        if(empty($uid))$uid = $user['id'];
        $new_status = $status;
        if($status == $do_status){
            $update['status_flow'] = $status_flow;
            $update['status'] = $new_status;
        }
        elseif ($status < $do_status){
            for ($i = $status;$i<$do_status;$i++){

                //补之前的确认状态
                if(isset($give["status{$status}_sub"]))$update["status{$status}_sub"] = 2;

                $status ++;

                if(!strpos($status_flow,"_{$status}|") && !self::roleMillBool($user,$status,$give['is_process'])){
                    $update["status{$status}_time"] = time();
                    if($status_flow)$status_flow .= ",";
                    $status_flow .= "_{$status}|{$uid}_";
                }
                if(!self::roleMillBool($user,$status,$give['is_process']))$new_status = $status;

                //补现在的确认状态
                if(isset($give["status{$status}_sub"]))$update["status{$status}_sub"] = 2;

            }
        }
        elseif ($status > $do_status){
            $new_status_flow = '';
            $new_status = $do_status;
            foreach (explode(',',$status_flow) as $flow){
                $flow_arr = explode('|',trim($flow,'_'));
                if($flow_arr[0] <= $do_status)$new_status_flow .= ",_{$flow_arr[0]}|{$flow_arr[1]}_";
                else {
                    //补之前的确认状态
                    if(isset($give["status{$flow_arr[0]}_sub"]))$update["status{$flow_arr[0]}_sub"] = 1;
                    if(isset($give["status{$flow_arr[0]}_time"]))$update["status{$flow_arr[0]}_time"] = 0;
                }
            }
            $status_flow = trim($new_status_flow,',');

            $update['address_sn'] = '';
            $update['address_date'] = '';
            $update['address_time'] = '';
            $update['address_status'] = '';
            $update['car_id'] = '';
        }

        $update['status_flow'] = $status_flow;
        $update['status'] = $new_status;

        return $update;
    }
    //质检
    //-2:报废 -1:不合格 0:待质检 1:合格 2:已返修
    public static function quality($user=[],$post=[],$role=true){

        $last_status = self::$role[8]['status'][0];

        $where[] = ['give_sn','in',$post['give_sn']];
        $where[] = ['status','<=',$last_status];
        $list = Db::name('mill_order_archives_give')->where($where)->select();

        if(!empty($list)){
            foreach ($list as $give){
                //质检状态 -3:删减的产品 -2:报废 -1:不合格 0:待质检 1:合格 2:已返修
                $quality_status = $post['status'];
                //不合格的流水线 1开料，2钣金，3挂件喷涂，4复合，5发货
                $give_status = !empty($post['give_status'])?abs($post['give_status']):'';
                //产品当前状态
                $status = abs($give['status']);
                //遍历
                $status_sub = !empty($give_status)?$give_status:$status;

                $save = [
                    'quality_uid'           =>  $user['uid'],
                    'quality_status'        =>  $quality_status,
                    'quality_time'          =>  time(),
                    'quality_note'          =>  isset($post['quality_note'])?$post['quality_note']:'',
                ];

                if($quality_status<0){

                    //责任部门
                    $save['quality_flow_group'] = self::$quality_group[$give_status];

                    //重置发货信息
                    $save["car_id"] = '';
                    $save["address_sn"] = '';
                    $save["address_date"] = '';
                    $save["address_time"] = '';
                    $save["address_status"] = 0;

                    for($i = $status_sub;$i <= $last_status;$i++){
                        if(!empty($give["status{$status_sub}_sub"])){
                            $save["status{$status_sub}_sub"] = 0;
                        }
                    }

                    $status = -$give_status;
                }
                else $status = abs($status);

                // 验证权限
                if($role){
                    $roles = self::role($user,null,$post['status']);
                    if ($roles)errors($roles,['status_code'=>0,'status_str'=>$roles]);
                }

                $save['status'] = $status;

                if(Db::name('mill_order_archives_give')->where(['id'=>$give['id']])->update($save)){

                    //质检状态 -2:报废 -1:不合格 0:待质检 1:合格 2:已返修
                    //更新质检记录
                    $add = Db::name('mill_order_archives_give')->where(['id'=>$give['id']])->find();
                    $quality = Db::name('mill_order_archives_give_quality')->where(['give_sn'=>$give['give_sn']])->find();
                    if(empty($quality)){
                        unset($add['id']);
                        Db::name('mill_order_archives_give_quality')->insert($add);
                    }
                    else Db::name('mill_order_archives_give_quality')->where(['id'=>$quality['id']])->update($add);
                    /*//如果报废则自动补一件产品
                    if($quality_status == -2 && $give['quality_status'] != -2)self::repair($give['id']);*/
                    //如果报废则重置生产状态
                    if($quality_status == -2 && $give['quality_status'] != -2){
                        $save = [
                            'status'                =>  0,
                            'quality_status'        =>  0,
                            'status_flow'           =>  '',
                        ];
                        for($i = 1;$i <= $last_status;$i++){
                            if(!empty($give["status{$i}_time"])){
                                $save["status{$i}_time"] = 0;
                            }
                        }
                        Db::name('mill_order_archives_give')->where($where)->update($save);
                    }
                    //检查更新产品主体状态
                    if($status > 0)ArchivesModel::checkStatus($give['archives_id'],$status);
                }
            }

            return true;

        }
        return false;

    }

    //根据用户ID或扫码状态获取对应值
    static function giveStatusOrUid($status_flow=null,$uid=null,$status=null){
        $data = '';
        if($uid){
            $give_status = explode("|{$uid}_",$status_flow);
            $give_status = array_filter($give_status);

            if(substr_count($status_flow,"|{$uid}_") == 1)$give_status = $give_status[0];
            else $give_status = end($give_status);

            if(isset($give_status)){
                $give_status = explode(',_',$give_status);
                $data = trim(end($give_status),'_');
            }

        }
        elseif ($status){
            $uid = explode("_{$status}|",$status_flow);
            if(isset($uid[1])){
                $uid = $uid[1];
                $uid = explode(',_',$uid);
                $data = trim($uid[0],'_');
            }
        }

        return $data;
    }

    // 分配发货单号
    public static function getAddressSn($time = 0){

        $config = new ConfigModel();

        //默认今天时间
        if(empty($time))$time = time();
        $update_time = true;
        //如果不是今天时间，则根据历史发货单号分配
        if(date('Ymd',$time) != date('Ymd'))$update_time = false;

        //分配今天的发货单
        if($update_time) {
            $sort = $config->getConfig('mill_address_sn');
            //发货单号计数器，如果不是今天的计数器，则重置并更新计数器
            if (strpos($sort, date('Ymd')) === false)ConfigModel::where('name', 'mill_address_sn')->update(['value' => date('Ymd') . "-0"]);
            $sort = $config->getConfig('mill_address_sn');
        }
        //分配历史发货单
        else {
            $status = self::$role[8]['status'][0];
            $where = [
                ["status{$status}_time",'between time',[date('Y-m-d',$time),date('Y-m-d 23:59:59',$time)]]
            ];
            $sort = Db::name('mill_order_archives_give')->where($where)->order('address_sn desc')->value('DISTINCT address_sn');
            if(empty($sort))$sort =  date('Ymd',$time) . "-0";
        }
        $sort = explode('-', $sort)[1];
        $sort ++;

        //分配发货单号
        $address_sn = self::addressSn($time,$sort);
        //更新发货单号
        if($update_time)ConfigModel::where('name', 'mill_address_sn')->update(['value' =>date('Ymd')."-".($sort)]);

        return $address_sn;
    }

    //定时任务，超过24小时未确认发货，则自动发货
    static function taskSubGiveAddress($address_sn='',$address_time=''){

        //24小时
        $time = (time()-86400);
        //发货状态
        $status = self::$role[8]['status'][0];
        //按批次分组
        $where = [
            ['address_sn','<>',''],
            ['status','=',$status],
            ['address_status','=',0],
        ];
        if(empty($address_sn)){
            $where[] = ["status{$status}_time",'>',0];
            $where[] = ["status{$status}_time",'<=',$time];
        }
        else $where[] = ['address_sn','=',$address_sn];

        $archives_ids = '';
        $give_list = Db::name('mill_order_archives_give')
            ->field("address_sn,order_pid,archives_sn,status{$status}_time,GROUP_CONCAT(id) as give_ids,GROUP_CONCAT(DISTINCT archives_id) as archives_ids")
            ->where($where)
            ->group('address_sn,order_pid')
            ->select();
        $address_sn_s = Db::name('mill_order_archives_give')->where($where)->column('address_sn');
        if(!empty($address_sn_s))$address_sn_s = implode(',',$address_sn_s);

        if(!empty($give_list)){

            foreach ($give_list as $v){

                $time = strtotime(date('Y-m-d 23:59:59',$v["status{$status}_time"]));
                if(!empty($address_time))$time = $address_time;

                $archives_ids .= ",{$v['archives_ids']}";
                //分配发货单号
                if(strpos($address_sn_s,$v['address_sn']) !== false){
                    $address_sn = $v['address_sn'];
                    $address_sn_s = str_replace($v['address_sn'],"",$address_sn_s);
                }
                else $address_sn = self::getAddressSn($time);

                if(!empty($v['give_ids'])){
                    $save = [
                        'address_status'        =>  1,
                        'address_date'          =>  date('Y-m-d',$time),
                        'address_time'          =>  $time,
                        'address_sn'            =>  $address_sn,
                    ];

                    $give_where = [['id','in',$v['give_ids']]];

                    Db::name('mill_order_archives_give')->where($give_where)->update($save);
                    //dump("order_pid：{$v['order_pid']} address_sn：{$v['address_sn']}");
                    //dump($save);

                }

            }
            //exit;

            //检查更新产品主体状态
            if(!empty($archives_ids)){
                $archives_ids = explode(',',trim($archives_ids,','));
                foreach ($archives_ids as $archives_id){
                    ArchivesModel::checkStatus($archives_id,$status);
                }

            }

        }
    }

}
